package dk.itu.samd.group2.tagapastry.messages;

import java.io.IOException;
import java.util.Vector;

import rice.p2p.commonapi.Endpoint;
import rice.p2p.commonapi.Id;
import rice.p2p.commonapi.NodeHandle;
import rice.p2p.commonapi.rawserialization.InputBuffer;
import rice.p2p.commonapi.rawserialization.OutputBuffer;
import dk.itu.samd.group2.tagapastry.IndexEntry;
import dk.itu.samd.group2.tagapastry.IndexEntryImpl;
import dk.itu.samd.group2.tagapastry.Merger;
import dk.itu.samd.group2.tagapastry.Tag;
import dk.itu.samd.group2.tagapastry.TagFactory;
import dk.itu.samd.group2.tagapastry.TagapastryClient;
import dk.itu.samd.group2.tagapastry.TagapastryImpl;

public class ResultsMsg extends TagapastryMsg {

	public static final short TYPE = 3;
	private static final long serialVersionUID = TYPE;
	private Vector<IndexEntry> newResults;

	public ResultsMsg(Tag tag, NodeHandle sender, NodeHandle recepientID, Vector<IndexEntry> resultsVec) {
		super(tag, sender, recepientID);
		this.newResults = resultsVec;
	}

	public ResultsMsg(InputBuffer buf, Endpoint endpoint) throws IOException {
		super(buf, endpoint);
		boolean resultsExist = buf.readBoolean();
		if (resultsExist) {
			int resultsSize = buf.readInt();
			newResults = new Vector<IndexEntry>(resultsSize);
			for (int i = 0; i < resultsSize; i++) {
				newResults.add(new IndexEntryImpl(buf));
			}
		}
	}

	@Override
	public void execute(TagapastryImpl taga) {

		// Results delivered
		//if(taga.getClient().canSend())
		//	taga.getClient().getMsgCollector().updateSearchMsgTime(this);
		
		// Count number of result messages
		taga.getClient().getMsgCollector().decSent();
		TagapastryClient client = taga.getClient();

		/* No need for heavily load testing
		if(tag.isComplex()) {
			tag = TagFactory.duplicateTagAlternateName(tag);
		}
		
		Vector<IndexEntry> results = taga.getSearchResults(tag);
		if (results != null) {
			newResults = Merger.merge(results, newResults);
		}
		
		taga.putResults(tag, newResults);
		*/
		client.searchResultsDelivery(tag, newResults);
	}
	
//	private void print(Vector<IndexEntry> data) {
//		for(IndexEntry ie : data)
//			System.out.println(ie);
//	}

	@Override
	public short getType() {
		return TYPE;
	}

	@Override
	public void serialize(OutputBuffer buf) throws IOException {
		super.serialize(buf);
		buf.writeBoolean(newResults != null);
		if (newResults != null) {
			buf.writeInt(newResults.size());
			for (IndexEntry entry : newResults) {
				entry.serialize(buf);
			}
		}
	}

	@Override
	public String toString() {
		String str = super.toString();
		str += " }";
		return str;
	}

	@Override
	public Id getRecepientId() {
		return recepientHandle.getId();
	}
	
	public int getSize() {
		int size = super.getSize();
		for(IndexEntry ie : newResults) {
			size += ie.getSize();
		}
		
		return size;
	}

}
